package com.javasee.common.dbsharding;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
@Slf4j
public class DbShardingRouterFactory {

//    private static CLoggerger cLogger = CLogger.getCLogger(DbShardingRouterFactory.class);

    private static DbShardingProperties properties;

//    private static JedShardingProperties jedProperties;
//
//    private static JedLogShardingProperties jedLogProperties;

//    public DbShardingRouterFactory(DbShardingProperties dbShardingProperties, JedShardingProperties jedProperties,
//                                   JedLogShardingProperties jedLogProperties) {
    public DbShardingRouterFactory(DbShardingProperties dbShardingProperties){
        DbShardingRouterFactory.properties = dbShardingProperties;
//        DbShardingRouterFactory.jedProperties = jedProperties;
//        DbShardingRouterFactory.jedLogProperties = jedLogProperties;
    }

    private static Map<String, DbShardingRouter> routerMap = new HashMap<>();

    public static synchronized DbShardingRouter getRouter(String tbName) {
        DbShardingRouter router = null;
        if (routerMap.containsKey(tbName)) {
            router = routerMap.get(tbName);
        } else {
            router = initRouter(tbName);
            routerMap.put(tbName, router);
        }
        return router;
    }

    private static DbShardingRouter initRouter(String tbName) {
        String routerClassName = "com.javasee.common.dbsharding.router.MurmurHashRouter";
        try {
            DbShardingTableInfo info = properties.getTables().get(tbName);

            //未设置分库分表的，默认第一个库，单表
            if (Objects.isNull(info) || info.getDbSize() == 1 && info.getTbSize()==1) {
                routerClassName = "com.javasee.common.dbsharding.router.SingleRouter";
            }else{
                if (info.getRouterClass() != null) {
                    routerClassName = info.getRouterClass();
                }
            }
            Class<?> clazz = Class.forName(routerClassName);
            Constructor constructor = clazz.getConstructor(Integer.class, Integer.class);

            //未配置，表示单库单表
            if(Objects.isNull(info)){
                return (DbShardingRouter) constructor.newInstance(1, 1);
            }
            return (DbShardingRouter) constructor.newInstance(info.getDbSize(), info.getTbSize());
        } catch (Exception e) {
//            log.error("initRouter", "", "加载表{}路由{}失败", e, tbName, routerClassName);
            throw new RuntimeException(e);
        }
    }

    public static void scanTable(String tableName, Consumer<DbshardingContext> consumer){
        DbShardingTableInfo table = properties.getTables().get(tableName);
//        if(Objects.isNull(table)){
//            table = jedProperties.getTables().get(tableName);
//        }
//        if(Objects.isNull(table)){
//            table = jedLogProperties.getTables().get(tableName);
//        }
        for (int dbIndex = 0; dbIndex < table.getDbSize(); dbIndex++) {
            for (int tbIndex = 0; tbIndex < table.getTbSize(); tbIndex++) {
                DbShardingContextHolder.set(tableName, dbIndex, tbIndex);
                consumer.accept(DbShardingContextHolder.get());
            }
        }
    }
}
